﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.Extensions.DependencyInjection;

namespace _001_依赖注入
{
    /// <summary>
    /// 依赖注入：构造函数注入示例
    /// </summary>
    internal class Program
    {
        /// <summary>
        /// 依赖解析过程：
        ///（1）有人请求 LoggerService。（service.AddTransient<LoggerService>();）
        ///（2）DI 容器发现 LoggerService 的构造函数需要 ILogger。
        ///（3）DI 容器根据之前的注册（AddTransient<ILogger, ConsoleLogger>()）提供一个 ConsoleLogger 实例。
        ///（4）DI 容器用 ConsoleLogger 实例创建 LoggerService 并返回。
        /// </summary>
        /// 
        static void Main(string[] args)
        {
            //依赖注入容器：（负责管理依赖的对象，负责依赖的注册、解析和生命周期管理）

            //(1)做一个容器的生成类（创建DI容器）
            var service = new ServiceCollection();
            //(2)注册容器里的服务信息（注册服务：依赖ConsoleLogger）
            service.AddTransient<ILogger, ConsoleLogger>();//向DI容器注册接口ILogger与实现类ConsoleLogger的映射关系
            service.AddTransient<LoggerService>();//注册一个没有显示实现的类
            //(3)生成我们的容器（构建容器并解析服务）
            var serviceProvider =service.BuildServiceProvider();//构建容器
            //从依赖注入（DI）容器中获取一个 LoggerService 的实例，并将其赋值给变量 loggerService。
            var loggerService = serviceProvider.GetRequiredService<LoggerService>();
            //(4)通过容器进行服务调用（调用方法）
            loggerService.LogMessage("This is a log Message");

        }

    }
    /// <summary>
    /// 接口ILogger
    /// LoggerService类依赖于接口ILogger
    /// ConsoleLogger是接口ILogger的实现
    /// </summary>
    public interface ILogger
    {
        void Log(string message);
    }

    /// <summary>
    /// 接口ILogger的实现
    /// 如果有其他需要，仅仅需要新增实现ILogger接口的类，
    /// 然后把(2)注册容器里的服务信息里面的ConsoleLogger，换成新的类名就可以了，
    /// 其他的完全不用改动
    /// </summary>
    public class ConsoleLogger : ILogger
    {
        public void Log(string message)
        {
            Console.WriteLine("控制台日志"); ;
        }
    }

    /// <summary>
    /// 构造函数注入方式
    /// 通过类的构造函数传递
    /// 依赖ILogger的服务，通过构造函数注入ILogger
    /// 解耦：LoggerService 不直接依赖 ConsoleLogger，而是依赖抽象 ILogger
    /// </summary>
    public class LoggerService
    {
        private readonly ILogger _logger;

        public LoggerService(ILogger logger)
        {            
                _logger = logger;         
        }
        public void LogMessage(string message)
        {
            _logger.Log(message);
        }
    }
}
